"use strict"

/**
 * @tfjs-vis库的扩充方法，即各类图表的呈现方法
 *   showVisor() 打开图表栏
 *   renderScatterPlot() 将数据渲染为散点图
 */

/**
 * @库导入
 */
// 导入tfvis库
import * as tfvis from "@tensorflow/tfjs-vis"

/**
 * 打开图表栏
 */
export function showVisor() { try {
  // 如果图表栏未打开，则打开
  if (!tfvis.visor().isOpen()) {
    tfvis.visor().open()
  }
} catch (error) {
  console.error("showVisor()报错：", error)
}}

/**
 * 将数据渲染为散点图
 * @param {{ tab: String, name: String }} container 容器对象
 * @param {{ x?: Number[], y: Number[] }[] } dataArr 用于生成图表的数据对象数组
 * @param { String[] } [serieTagArr] 序列名称数组
 * @param { xLabel: String, yLabel: String } [label] x轴和y轴标签
 * @example
 * ```js
 * // 绘图预览
 * renderScatterPlot(
 *   // 图表容器
 *   { tab: "测试数据", name: "原始数据" },
 *   // 图表数据
 *   [
 *     { x: x[], y: origin[] },
 *     { x: x[], y: corrected[] },
 *     { x: x[], y: baseline[] },
 *   ],
 *   // 数据序列标签
 *   ["原始数据", "校正", "基线"],
 * )
 * ```
 */
export function renderScatterPlot(container, dataArr, serieTagArr, label) { try {
  // 先检查dataArr和serieTagArr长度是否一致
  const dataArrLength = dataArr.length
  // 如果提供了serieTagArr，则检查长度是否一致
  if (serieTagArr && (dataArrLength !== serieTagArr.length)) {
    throw new Error(`数据组数和其标签数不一致，请检查`)
  }
  // 建一个框，用于装JSON化的Aoa数据
  // 即每一个最小单元是{x, y}对象，一组数据为{x, y}[]，多组数据形成{x, y}[][]
  const dataJsonAoa = []
  // 根据是否指定x值分开作图
  // 如果提供了x值，则按x值作图
  if (dataArr[0].x && (dataArr[0].x[0] || dataArr[0].x[0] === 0)) {
    // 遍历dataArr传参，按每一组来处理
    for (let i = 0; i < dataArrLength; i++) {
      // 取数据、y[]的数据量
      const data = dataArr[i]
      const dataLength = data.y.length
      // 先比较x[]和y[]的长度是否一致
      if (data.x.length !== dataLength) {
        throw new Error(`第 ${ i } 组数据的X和Y数据长度不一致，请检查`)
      }
      // 建一个框，用于装JSON化的Arr数据，即一堆{x, y}的数组
      const dataJsonArr = []
      // 遍历dataAoa里的Arr数据，提取{x, y}
      for (let j = 0; j < dataLength; j++) {
        // 把{x, y}推入dataJsonArr框
        dataJsonArr.push({
          x: data.x[j],
          y: data.y[j],
        })
      }
      // 把dataJsonArr推入dataJsonAoa框
      dataJsonAoa.push(dataJsonArr)
    }
  // 如果没提供x值，就方便了
  } else {
    // 遍历dataArr传参，按每一组来处理
    for (let i = 0; i < dataArrLength; i++) {
      // 取数据、y[]的数据量
      const data = dataArr[i]
      const dataLength = data.y.length
      // 建一个框，用于装JSON化的Arr数据，即一堆{y}的数组
      const dataJsonArr = []
      // 遍历dataAoa里的Arr数据，提取{y}
      for (let j = 0; j < dataLength; j++) {
        // 把{x, y}推入dataJsonArr框
        dataJsonArr.push({ y: data.y[j] })
      }
      // 把dataJsonArr推入dataJsonAoa框
      dataJsonAoa.push(dataJsonArr)
    }
  }
  // 作图
  tfvis.render.scatterplot(
    // 容器对象
    container,
    // 数据
    {
      // 数据集
      values: dataJsonAoa,
      // 数据序列标签，有则赋值，否则undefined
      series: serieTagArr || undefined,
    },
    // 额外参数
    {
      // X轴是波数
      xLabel: label?.xLabel || "wavenumber(cm-1)",
      // Y轴是计数
      yLabel: label?.yLabel || "counts",
      // 自动缩放
      zoomToFit: true
    }
  )
} catch (error) {
  console.error("renderScatterPlot()报错: ", error)
  throw new Error(error)
}}
